#include "imagem.h"


/* inicializa a avail list*/
void cria_avail () {
	FILE * avail_head;
	int i;
	
	avail_head = fopen ("avail_head.dat", "w");
	
	for(i=0; i<5; i++) 
		fprintf(avail_head, "%.3d",FIM_AVAIL);

	fclose(avail_head);
}

/* remove a obra desejada */
void remocao(pNo_PK *obras, pNo_PK *sk_titulo, pNo_PK *sk_tipo, pNo_PK *sk_autor, pNo_PK *sk_ano, int *tamanho, int ttitulo, int ttipo, int tautor, int tano) {
		
		FILE * base, *pk_titulo, *pk_tipo, *pk_autor, *pk_ano;
		char *titulo, *autor, *tipo, *ano;
		int pointer;
		pNo_PK busca;
			
			titulo = malloc(sizeof(char)*(tam_titulo+1));
			tipo = malloc(sizeof(char)*(tam_tipo+1)); 
			autor = malloc(sizeof(char)*(tam_autor+1)); 
			ano = malloc(sizeof(char)*(tam_ano+1 )); 
	__fpurge(stdin);
	printf("\nPara a remocao, deve-se digitar o titulo completo da obra, com distincao entre maiusculas e minusculas.\n");
	printf("Digite o titulo da obra a ser removida: ");
	remove_espacos();
			fgets(titulo, tam_titulo, stdin);
			completa_espacos(titulo, tam_titulo);

	/*procura a obra desejada */
	if((busca = bsearch (titulo, *obras, *tamanho, sizeof (struct No_PK), (int(*)(const void*,const void*))compara))) {
			
			/* guarda os campos em strings para uso posterior da remocao */
			base = fopen("base00.dat", "r");
			pointer = (((busca->nrr) - 1)*tam_total)+tam_titulo;
			fseek(base, pointer, SEEK_SET);

			
			fgets(tipo, tam_tipo+1, base);
			fgets(autor, tam_autor+1, base);
			fgets(ano, tam_ano+1, base);
			fclose(base);


			
			/*remove e manipula avail list */
			remove_base(busca);
			remove_PK(&(*titulo), &(*obras), &(*tamanho));
			
			Str_toupper(titulo); /* transforma em maiusculo */
			Str_toupper(tipo); /* transforma em maiusculo */
			Str_toupper(autor); /* transforma em maiusculo */



			pk_titulo = fopen("pk_titulo.dat", "r+");
			pk_tipo = fopen("pk_tipo.dat", "r+");
			pk_autor = fopen("pk_autor.dat", "r+");
			pk_ano = fopen("pk_ano.dat", "r+");


			remove_SK(&(*titulo), ttitulo, &(*sk_titulo), pk_titulo, &(*titulo), pos_titulo, tam_titulo);
			remove_SK(&(*tipo), ttipo, &(*sk_tipo), pk_tipo, &(*titulo), pos_tipo, tam_tipo);
			remove_SK(&(*autor), tautor, &(*sk_autor), pk_autor, &(*titulo), pos_autor, tam_autor);
			remove_SK(&(*ano), tano, &(*sk_ano), pk_ano, &(*titulo), pos_ano, tam_ano);


			fclose(pk_titulo);
			fclose(pk_tipo);
			fclose(pk_autor);
			fclose(pk_ano);
			
			printf("\nObra removida com sucesso!\n\n");
			
			
			

	}


	else {	
		printf("\nNenhuma obra correspondente encontrada.\n\n");
	}
	
			free(titulo);
			free(tipo);
			free(autor);
			free(ano);

}


void remove_base(pNo_PK busca) {

			FILE *avail_head;
			FILE *base;
			char aux[6];
			int i, atual;

/* armazena na string aux o nrr do comeco da avail list */
			avail_head = fopen("avail_head.dat", "r+");
			fgets(aux, 5, avail_head);
			atoi(aux);
		
			/* coloca o nrr do arquivo removido no comeco da avail list */
			rewind(avail_head);
			fprintf(avail_head,"%.4d", busca->nrr);
			fclose(avail_head);

			/* coloca o nrr que estava no comeco da avail list para o local do registro removido */
			base = fopen("base00.dat", "r+");
			atual = ((busca->nrr) - 1) * tam_total;
			fseek(base, atual, SEEK_SET);
			fputs(aux, base);

		fprintf(base, "*");
		for(i=0; i<(tam_total-5); i++) {
			fputs(" ", base);
		}
		
		fclose(base);
}

void remove_SK(char *chaves, int tamanho, pNo_PK *SK, FILE *arquivo, char *titulo, int position, int tam_str) {

	char *p, *chave_aux, *chave_aux2, *chave;

	chave = malloc(sizeof(char)*(tam_str+1));
	chave_aux = malloc(sizeof(char)*(tam_str+1));
	chave_aux2 = malloc(sizeof(char)*(tam_str+1));

	strcpy(chave, chaves);
	strcpy(chave_aux,chave);
	p = strtok (chave," ");
	Str_toupper(chave_aux);
	Fillblanks(chave_aux, tam_str);
	if ((p = strtok(NULL, " "))) { /* realiza a verificacao se uma str eh composta, caso seja, adicionara o titulo completo primeiramente */
		remove_aux(chave_aux, tamanho, &(*SK), arquivo, &(*titulo), position);

	}
	p = strtok(chave_aux," "); 
	strcpy(chave_aux2,p);
	Str_toupper(chave_aux2);
	Fillblanks(chave_aux2, tam_str);
	while (p) { /*adicao do titulo quebrado em pedacos (strtok) ate chegar ao final (NULL) */
		remove_aux(chave_aux2, tamanho, &(*SK), arquivo, &(*titulo), position);

		if ((p = strtok (NULL," "))) {
			strcpy(chave_aux2,p);		/* quebra novamente e mantem o while ate null */
			Str_toupper(chave_aux2);
			Fillblanks(chave_aux2, tam_str);
		}
	}
	free(chave);
	free(chave_aux);
	free(chave_aux2);
	
}

void remove_aux(char *chave, int tamanho, pNo_PK *SK, FILE *arquivo, char *titulo, int position) {

	FILE * avail_head;
	pNo_PK busca;
	int atual, ponto, anterior=0, contador = 0, i;
	char *string;
	char aux[dig_nrr+2], prox[dig_nrr+2];

	/* procura titulo */
	if((busca = bsearch (chave, *SK, tamanho, sizeof (struct No_PK), (int(*)(const void*,const void*))compara))) {
		ponto = busca->nrr; 
		string = malloc(sizeof(char)*(tam_titulo+2));
		do {
	
	
			atual = (ponto-1)*(tam_titulo+dig_nrr);
			rewind(arquivo);
			fseek(arquivo, atual, SEEK_SET);
			fgets(string, tam_titulo+1, arquivo); /*pega a chave primaria e armazena na string */
			string[tam_titulo+1] = '\0';
			fgets(prox, dig_nrr+1, arquivo); /* pega o proximo endereco */
			prox[dig_nrr+1] = '\0';

			Str_toupper(string);
			/* compara string */
			if(strcmp(string, titulo) == 0) {
			/* 1º caso de remocao */
			if(contador == 0) {
				busca->nrr = atoi(prox);
			/* 2º caso de remocao */
			}
			else {				
				fseek(arquivo, ((anterior-1)*(tam_titulo+dig_nrr) + 200), SEEK_SET);
				fputs(prox, arquivo);
			}
			
			avail_head = fopen("avail_head.dat", "r+");
			fseek(avail_head, dig_nrr*position, SEEK_SET);
			fgets(aux, dig_nrr+1, avail_head);
			rewind(avail_head);
			fseek(avail_head, dig_nrr*position, SEEK_SET);
			fprintf(avail_head,"%.4d", ponto);
			fclose(avail_head);

			/* coloca o nrr que estava no comeco da avail list para o local do registro removido */
			rewind(arquivo);
			fseek(arquivo, atual, SEEK_SET);
			fputs(aux, arquivo);

			fprintf(arquivo, "*");
			for(i=0; i<(tam_titulo-1); i++) {
				fputs(" ", arquivo);
			}
			
		}
		else{
			anterior = ponto;
			contador++;
		} 

		ponto = atoi(prox);

	} while(ponto != -1);
	free(string);
	}
}

void remove_PK(char *titulo, pNo_PK *obras, int *tam_nrr) {

	
	pNo_PK removido;

	removido = bsearch (titulo, *obras, *tam_nrr, sizeof (struct No_PK), (int(*)(const void*,const void*))compara); /* procura a obra no vetor */


	strcpy(removido->titulo, (*obras)[*tam_nrr-1].titulo);
	removido->nrr = (*obras)[*tam_nrr-1].nrr;

	*tam_nrr -=1;
	qsort(*obras, *tam_nrr, sizeof(struct No_PK), (int(*)(const void*,const void*))compara);

}
